/*
 * mri_utils.h
 *
 *  Created on: Apr 16, 2009
 *      Author: alex
 */

#ifndef MRI_UTILS_H_
#define MRI_UTILS_H_

#include <stdio.h>
#include <time.h>
#include <complex.h>
#include <assert.h>
#include <stdlib.h>

typedef struct {
	int ndims;
	int* dims;
	int* gaps; // TODO: fill this vector on matrix read & allocate
} mri_matrix_descriptor_t;

/**
 * Starts an internal tick counter and prints a message to stdout
 */
void mri_tic();

/**
 * Stops the internal tick counter and prints a message to stdout
 * indicating the number of elapsed seconds
 */
void mri_toc();

/**
 * Prints to file f a string representing the complex number x,
 * using the following format: %f+/-%fi
 */
void mri_write_complex(FILE* f, complex float x);

/**
 * Prints to file f a string representing the complex-valued matrix m,
 * using comma separated values with the following format:
 *  - the first value is an integer representing number of dimensions ndims
 *  - the next ndims values are integers representing each dimension
 *  - following are the matrix values in %f+/-%fi format TODO: order?...
 * The information about matrix dimensions is taken from the matrix descriptor desc
 */
void mri_write_complex_matrix(FILE* f, complex float* mat, mri_matrix_descriptor_t* desc);

/**
 * Prints to file f a string representing the real-valued matrix m,
 * using comma separated values with the following format:
 *  - the first value is an integer representing number of dimensions ndims
 *  - the next ndims values are integers representing each dimension
 *  - following are the matrix values in %f+/-%fi format TODO: order?...
 * The information about matrix dimensions is taken from the matrix descriptor desc
 */
void mri_write_real_matrix(FILE* f, float * mat, mri_matrix_descriptor_t* desc);

/**
 * Reads the a complex value from the file f into the location pointed by
 * result. Returns 1 on success or EOF when reaching end of file
 */
int mri_read_complex(FILE* f, complex float * result);

/**
 * Attempts to allocate and read a complex-valued matrix from input file f.
 * The data must be formatted as described by mri_write_complex_matrix
 * The provided pointers shall hold:
 *  ndims - number of matrix dimensions
 *  dims - vector of matrix dimensions
 *  mat - the values of the matrix
 *
 */
complex float* mri_read_complex_matrix(FILE* f, mri_matrix_descriptor_t* desc);

/**
 * Attempts to allocate and read a real-valued matrix from input file f.
 * The data must be formatted as described by mri_write_complex_matrix
 * The provided pointers shall hold:
 *  ndims - number of matrix dimensions
 *  dims - vector of matrix dimensions
 *  mat - the values of the matrix
 *
 */
float* mri_read_real_matrix(FILE* f, mri_matrix_descriptor_t* desc);

/**
 * Sets the working path for MRI library.
 */
void mri_set_path(char* path);

/**
 * Returns the working path for MRI library.
 */
char* mri_get_path();

/**
 *  Returns a new string containing all given strings concatenated.
 */
char* mri_strcat(int nstr, char* str1, ...);

/**
 * Loads the matrix from <filename>.csv
 */
float* mri_load_real_matrix(char* matrixname, mri_matrix_descriptor_t* desc);

/**
 * Loads the matrix from <filename>.csv
 */
complex float* mri_load_complex_matrix(char* matrixname, mri_matrix_descriptor_t* desc);

/**
 * Saves the matrix to <filename>.csv
 */
void mri_save_real_matrix(char* matrixname, float* mat, mri_matrix_descriptor_t* desc);

/**
 * Saves the matrix to <filename>.csv
 */
void mri_save_complex_matrix(char* matrixname, complex float* mat, mri_matrix_descriptor_t* desc);



/**
 * TODO: implement free methods
 */
#endif /* MRI_UTILS_H_ */
